home *** CD-ROM | disk | FTP | other *** search
/ Network Supervisor's Toolkit / Network Supervisor's Toolkit.iso / tools / lu62 / int68.c < prev    next >
C/C++ Source or Header  |  1996-07-10  |  33KB  |  1,205 lines

  1. /*
  2.  * This file contains some functionally close enough subroutines which
  3.  * have deal with initial and ending phases of the LU 6.2 verb processing.
  4.  *
  5.  * The "rout" subroutine represents the main entry point of the APPC
  6.  * (Advanced Program to Program Communication or in other words LU 6.2)
  7.  * module. This is in fact the first subroutine which has deal with
  8.  * processing of APPC requests.
  9.  * The APPC requests may come from two sources:
  10.  * - from application program via int 68h, or from
  11.  * - remote APPC module via network.
  12.  *
  13.  * CopyRight 1995. Nicholas Poljakov all rights reserved.
  14.  *
  15.  */
  16. #include <dos.h>
  17. #include <malloc.h>
  18. #include <stdlib.h>
  19. #include <rcb.h>
  20. #include <common.h>
  21. #include <attlu.h>
  22. #include <detach.h>
  23. #include <tcb.h>
  24. #include <scb.h>
  25. #include <rpl.h>
  26. #include <nib.h>
  27. #include <mode.h>
  28. #include <tps.h>
  29. #include <partner.h>
  30. #include <repass.h>
  31. #include <stdio.h>
  32. #include <include.h>
  33. #include <string.h>
  34. #include <fcntl.h>                /* @0100 */
  35. #include <process.h>
  36. #include <arcb.h>
  37. #include <rcballoc.h>
  38. #include <crtp.h>
  39. #include <state1.h>
  40.  
  41. #include <sys\types.h>
  42. #include <sys\stat.h>
  43.  
  44. int sk_r_wt(void *);
  45. int SendBlock(void *, void *);
  46. int setrc(void *, void *);
  47. int sendhsf(void *);
  48. int sendhs(void *);
  49. int sendbm(void *, void *);
  50. int sendat(void *);
  51. int rtsend(void *);
  52. unsigned long rmfmh5(void *, void *);
  53. int recwait(void *);
  54. int rcvru(void *, void *);
  55. int rcvhs(void *, void *, void *, void *);
  56. int ralloc(void *, void *);
  57. int psrm(int, void *, void *);
  58. int ps_conv(int, void *);
  59. int proterr(void *, unsigned long);
  60. int preptrcv(void *, void *);
  61. int post_rcb(void *);
  62. struct repass *postopen(void *);
  63. int phsrec(void *);
  64. int pfmh5(void *);
  65. int opndst(void *);
  66. int obtsess(void *, unsigned char);
  67. int Lrf_handler(void *);
  68. int get_sess(void *, void *);
  69. int get_attr(void *);
  70. int fsm_error(unsigned char, void *);
  71. int fsm_conv(unsigned char, unsigned char, void *);
  72. int flush (void *);
  73. int dcp(void *);
  74. int dealloc(void *);
  75. int crtp(void *);
  76. int conv(void *);
  77. int chkparm(void *, void *);
  78. int check_end(unsigned int, void *);
  79. int close_acb(void *);
  80. struct rqb *call_appl(void *);
  81. int buffmng(unsigned char, void *, void *, void *, unsigned, unsigned char, unsigned);
  82. unsigned long attltck(void *);
  83. unsigned long attacheck(void *);
  84. int lu_init(void *);
  85. int lu_sdown(void *);
  86. int clt_vb(unsigned int, void *);
  87. int sessi(unsigned int, void *);
  88. int sessd(unsigned int, void *);
  89. int fpost(void *);
  90. int seek_res(void *);
  91. char *cgetmem(int, int);
  92. int sendhsf(void *);
  93. int opndst(void *);
  94. int alloc_rcb(void *, void *);
  95. int allocate(void *);
  96. int clsdst(void *);
  97. unsigned long calltpn(void *, void *);
  98.  
  99. extern unsigned ProgPrefix;
  100.  
  101. struct psp {
  102.        struct lucb *lucb_list_ptr; /* π¬áºáΓѽ∞ ¡á ß»¿ß«¬ lucb */
  103.        struct tcb  *tcb_list_ptr ; /* π¬áºáΓѽ∞ ¡á ß»¿ß«¬ tcb  */
  104.        struct rcb  *rcb_list_ptr ; /* π¬áºáΓѽ∞ ¡á ß»¿ß«¬ rcb  */
  105.        struct rcb  *wait_chain;    /* «τÑpÑñ∞ «ª¿ñáεΘ¿σ RCB */
  106.        char    *param;
  107.      } psp_ini = {NULL, NULL, NULL, NULL, NULL};
  108. struct lucb {
  109.        char    lu_id[8];     /* ¿ñÑ¡Γ¿Σ¿¬áΓ«α ½«¬á½∞¡«ú« LU */
  110.        unsigned char rsrv1;
  111.        char    lu_name[8];   /* ¿¼∩ LU */
  112.        unsigned char rsrv2;
  113.        struct  acb *p_acb;
  114.        struct pnlu *pluptr;  /* π¬áºáΓѽ∞ ¡á
  115.                               * ß»¿ß«¬ partner_lu   */
  116.        struct  trp *trp_ptr;    /* π¬áºáΓѽ∞ ¡á
  117.                                  * transaction_program_list  */
  118.        struct pending_data_list *pdlptr; /* ß»¿ß«¬ ñá¡¡δσ,
  119.                                           * »«ß½á¡¡δσ ó BIND
  120.                                           * ¬ »áαΓ¡Ñαπ */
  121.        struct mode *p_mode; /* List of mode blocks for this LU */
  122.        struct scb *scb_list;
  123.        unsigned char lu_session_limit;  /* ¼á¬ß¿¼á½∞¡«Ñ ¬«½¿τÑßΓó«
  124.                                     ßÑßß¿⌐ LU-LU ñ½∩ ½«¬á½∞¡«ú« LU */
  125.        unsigned char cur_sess; /* current number of sessions*/
  126.        int  max_tps; /* max. number of total tps for this LU */
  127.        int  cur_tps; /* current number of tps */
  128.        int  queue_depth;
  129.        struct tcb  *tcb_list_ptr ; /* π¬áºáΓѽ∞ ¡á ß»¿ß«¬ tcb  */
  130.        struct lucb *next; /* next LUCB */
  131.     } lu6;
  132. struct acb {
  133.  short rsrv1;
  134.  short leng;
  135.  char rsrv2[4];
  136.  unsigned long int iface;
  137.  char rsrv3;
  138.  unsigned macr2:8;
  139.  struct acb *acb_next;
  140.  struct rpl *rpl;
  141.  char rsrv4[10];
  142.  unsigned long int passw;
  143.  unsigned long int uel;
  144.  char rsrv5[3];
  145.  unsigned am:8;          /* 0x60-NTAM           */
  146.  unsigned long int deb;
  147.  unsigned oflgs:8;       /* 0x10-OPEN           */
  148.  unsigned erflg:8;       /* 0x04-ALREADY OPEN   *
  149.                           * 0x14-NOT ENOUGH STORAGE*/
  150.  char rsrv6[22];
  151.  unsigned long int apid;
  152.  char rtn[6];
  153. } acb_ini;
  154.  
  155. int sw_retry[10];
  156. char dispflag;
  157. struct rcb *wait_rcb;
  158.  
  159. extern void (_interrupt _far *oldint68)( void );
  160. extern char svarea;
  161. extern char _huge *tsrstack;
  162. char _huge *altstack;
  163. char _huge *altsave;
  164.  
  165. extern char lupost;
  166. void _far *tp_exit;
  167. char *buff;
  168.  
  169. /*  Literal pool */
  170.  
  171. char name_lu6[8] = "LU6****";
  172. /* char name6[8] = "MODE6**";
  173. char name0[8] = "MODE0**";
  174. char name_tp[8] = "TP00001"; */
  175. char tpi[6] = "TPXXX";
  176.  
  177.             unsigned int code;  /* Verb code */
  178.             unsigned int SaveCode[10];
  179.             unsigned int mask;
  180.             char *s_ptr;    /* Pointer to verb record */
  181.             char *SavePtr[10];
  182.             char *t_ptr;
  183.             int from_appl[10];
  184.             int ss_ptr = 0;
  185.             char *temp;
  186.             struct in_parm {
  187.                              unsigned int  verb_cd;
  188.                              unsigned long verb_ptr;
  189.                             } parm;
  190.             struct repass *p_rep;
  191.             struct rqb *p_rqb;
  192.  
  193. #define HSrec 0x00ff
  194.  
  195. void _interrupt _far rout( unsigned _es, unsigned _ds, unsigned _di,
  196.                    unsigned _si, unsigned _bp, unsigned _sp,
  197.                    unsigned _bx, unsigned _dx, unsigned _cx,
  198.                    unsigned _ax, unsigned _ip, unsigned _cs,
  199.                    unsigned _flags )
  200. {
  201.         /*
  202.          * Map of svarea -
  203.          *        offset : 0 - sp of application programm
  204.          *        offset : 2 - ss of application programm
  205.          *        offset : 4 - sp of "appl" part of PORT
  206.          *        offset : 6 - ss of "appl" part of PORT
  207.          *        offset : 8 - ds of LU module.
  208.          *        offset : 20 - pointer to psp_ini
  209.          */
  210.  
  211.         /* Save current stack of application, and set old stack of TSR.
  212.          * This is for safety since we don't know the state of the
  213.          * application stack, but we do know the state of our own stack.
  214.          * Turn off interrupts during the stack switch.
  215.          */
  216.  
  217.         FP_SEG( s_ptr ) = _ds;
  218.         FP_OFF( s_ptr ) = _dx;
  219.         _disable();
  220.         code = _ax;
  221.         SaveCode[ss_ptr] = code; /* Save code for retry */
  222.         SavePtr[ss_ptr] = s_ptr;
  223.         _asm
  224.                 {
  225.                     mov  ax, seg svarea
  226.                     push es
  227.                     mov  es, ax
  228.                     mov  ax, ds
  229.                     mov  WORD PTR es:svarea[8], ax   ; Save data segment
  230.                     pop  es
  231.                 }
  232.         mask = code & 0x00ff;
  233.         if (mask == 0x00ff) { /* from APPL */
  234.             from_appl[ss_ptr] = YES;
  235.         p_rqb = (struct rqb *)s_ptr;
  236.             if (!(p_rqb ->th.ra.code & 0x7f)) {
  237.              /* Segment */
  238.                 s_ptr -= 12;
  239.             }
  240.             _asm
  241.             {
  242.                 mov  ax, seg svarea
  243.                 mov  es, ax
  244.                 mov  WORD PTR es:svarea[4], sp   ; Save current stack
  245.         mov  WORD PTR es:svarea[6], ss
  246.         mov  ax, seg altstack
  247.         mov  es, ax
  248.         mov  sp, WORD PTR es:altstack[0] ; Load LU stack
  249.         mov  ss, WORD PTR es:altstack[2]
  250.             }
  251.         }
  252.         else
  253.                 {
  254.                     from_appl[ss_ptr] = No;
  255.                     _asm
  256.                     {
  257.                         mov  ax, seg svarea
  258.                         mov  es, ax
  259.                         mov  WORD PTR es:svarea[0], sp   ; Save current stack
  260.             mov  WORD PTR es:svarea[2], ss
  261.             mov  ax, seg tsrstack
  262.             mov  es, ax
  263.             mov  sp, WORD PTR es:tsrstack[0] ; Load LU stack
  264.             mov  ss, WORD PTR es:tsrstack[2]
  265.                     }
  266.                 }
  267.  
  268.        ss_ptr++;
  269.  
  270.         _enable();
  271.  
  272.         /* Make APPC verb processing */
  273.  
  274.         /*
  275.          * Init. verb record if request from TP.
  276.          */
  277.         if ((code != POSTOPEN)&&(code != DR)&&
  278.             (code != FMHRCV)&&(code != SESSINI)&&
  279.             (code != CLSSESS)&&(code != CLSSESS)) {
  280.         p_rep = (struct repass *)s_ptr;
  281.             p_rep -> complete = 0;
  282.             p_rep -> p_rcb = NULL;
  283.             p_rep -> tp_fd = 0;
  284.         }
  285.  Retry :
  286.         switch (code) {
  287.           case LRF :     { /* Local resource failure */
  288.                              Lrf_handler(s_ptr);
  289.                              break;
  290.                          }
  291.  
  292.           case Attach_lu:
  293.                          {
  294.                              lu_init(s_ptr);
  295.                              break;
  296.                          }
  297.           case Detach_lu:
  298.                          {
  299.                              lu_sdown(s_ptr);
  300.                              break;
  301.                          }
  302.           case TP_STARTED:
  303.           case TP_ENDED:
  304.                          {
  305.                              clt_vb(code, s_ptr);
  306.                              break;
  307.                          }
  308.           case FMHRCV :  /* Record from HS, FMH-5 or FMH-7 header */
  309.                          {
  310.                              /* s_ptr points to RQB */
  311.                              s_ptr = (char *)s_ptr - 12;
  312.                              /* s_ptr points to SEGPRF now */
  313.                              phsrec(s_ptr);
  314.                              break;
  315.                          }
  316.           case SESSINI :
  317.                          {
  318.                              /* s_ptr points to RQB */
  319.                              s_ptr = (char *)s_ptr - 12;
  320.                              /* s_ptr points to SEGPRF now */
  321.                              sessi(code, s_ptr);
  322.                              break;
  323.                          }
  324.           case CLSSESP :
  325.           case CLSSESS :
  326.                          {
  327.                              sessd(code, s_ptr);
  328.                              break;
  329.                          }
  330.           case DR :
  331.                          {
  332.                              if (fpost(s_ptr) == 0) {
  333.                              }
  334.                              break;
  335.                          }
  336.           case CONVERT :
  337.                          {
  338.                              conv(s_ptr);
  339.                              break;
  340.                          }
  341.           case POSTOPEN:
  342.                          {
  343.                  t_ptr = (char *)postopen(s_ptr);
  344.                              temp = t_ptr;
  345.                              if (temp == NULL) {
  346.                                code = -1;
  347.                              }
  348.                              break;
  349.                          }
  350.           case Allocate:
  351.                          {
  352.                            ps_conv(code,s_ptr);
  353.                            break;
  354.                          }
  355.           case Confirm:
  356.           case COnfirmed:
  357.           case Deallocate:
  358.           case Flush:
  359.           case Get_attributes:
  360.           case Post_on_receipt:
  361.           case Prepare_to_receive:
  362.           case Receive_and_wait:
  363.           case Receive_immediate:
  364.           case Request_to_send:
  365.           case Send_data:
  366.           case Send_error:
  367.           case Test:
  368.            {
  369.               if (seek_res(s_ptr) == 0)
  370.                  {
  371.                     /* ¡á⌐ñÑ¡ ó ß»¿ß¬Ñ */
  372.                      ps_conv(code, s_ptr);
  373.                  }
  374.               break;
  375.            }
  376.           default : break;
  377.         }
  378.         /* Check if verb processing is complete.
  379.          * If it's true write response to TP FIFO,
  380.          * otherwise place RCB in wait qenue.
  381.          */
  382.         sw_retry[ss_ptr - 1] = No;
  383.         check_end(code, s_ptr);
  384.         if (sw_retry[ss_ptr - 1] == YES) {
  385.              sw_retry[ss_ptr - 1] = No;
  386.              code = SaveCode[ss_ptr - 1];
  387.              s_ptr = SavePtr[ss_ptr - 1];
  388.              goto Retry;
  389.         }
  390.  
  391.         /* Restore application stack. */
  392.         _disable();
  393.         if (from_appl[ss_ptr - 1] == YES) {
  394.             from_appl[ss_ptr - 1] = No;
  395.             _asm
  396.             {
  397.                 mov  ax, seg svarea
  398.                 mov  es, ax
  399.                 mov  sp, WORD PTR es:svarea[4]
  400.                 mov  ss, WORD PTR es:svarea[6]
  401.             }
  402.         }
  403.         else
  404.                 {
  405.                    _asm
  406.                    {
  407.                        mov  ax, seg svarea
  408.                        mov  es, ax
  409.                        mov  sp, WORD PTR es:svarea[0]
  410.                        mov  ss, WORD PTR es:svarea[2]
  411.                    }
  412.                 }
  413.     ss_ptr--;
  414. }
  415. seek_res(s_ptr)
  416. char *s_ptr;
  417. {
  418.   struct com *c;
  419.   struct tcb *t;
  420.   struct rcb *r;
  421.   struct repass *p_rep;
  422. #if OS_TYPE == 1
  423. /*********  Trace facility **********/
  424. unsigned int rtype;   /* type of record */
  425. unsigned int pnum;    /* point number */
  426. char pname[8];        /* name of module */
  427. char *drec;       /* record for dump */
  428. int  lenr;            /* record length */
  429. rtype = INPROC;
  430. strcpy(pname, "seek_rs");
  431. pnum = 1;
  432. drec = s_ptr;
  433. lenr = 200;
  434. gtf(rtype, pname, pnum, drec, lenr);
  435. /***********************************/
  436. #endif
  437.  
  438.   /*
  439.    * Seek LU_ID and TP_ID for this request
  440.    */
  441.   c = (struct com *)s_ptr;
  442.   p_rep = (struct repass *)s_ptr;
  443.   c -> prim_rc = OK;
  444.   c -> sec_rc = 0x00000000;
  445.  
  446.   t = lu6.tcb_list_ptr;
  447.   if (t == NULL) {
  448.       c -> prim_rc = PARAMETR_CHECK;
  449.       c -> sec_rc = 0xf0040000; /* Incomplete */
  450.       return(-1);
  451.   }
  452.   while (t != NULL) {
  453.       if (memcmp(c -> tp_id, t -> tcb_id, 8) != 0) {
  454.               goto next_tcb;
  455.       }
  456.       break;
  457.       next_tcb:
  458.                t = t -> next;
  459.   }
  460.   if (t == NULL) {
  461.       c -> prim_rc = PARAMETR_CHECK;
  462.       c -> sec_rc = 0x00000001; /* Bad tp_id */
  463.       return(-1);
  464.   }
  465.   r = t -> rcb_list_ptr;
  466.   if (r == NULL) {
  467.       c -> prim_rc = PARAMETR_CHECK;
  468.       c -> sec_rc = 0xf0040000; /* Incomplete */
  469.       return(-1);
  470.   }
  471.   while (r != NULL) {
  472.       if (c -> conv_id != r -> rcb_id) {
  473.          goto next_rcb;
  474.       }
  475.       break;
  476.       next_rcb:
  477.                r = r -> next;
  478.   }
  479.   if (r == NULL) {
  480.       c -> prim_rc = PARAMETR_CHECK;
  481.       c -> sec_rc = BAD_CONV_ID;
  482.       return(-1);
  483.   }
  484.   p_rep -> p_rcb = r;
  485.   return (0);
  486. }
  487.  
  488. lu_init(s_ptr)
  489. char *s_ptr;
  490. {
  491.     int j,k;
  492.     int t;
  493.     unsigned int addr;
  494.     unsigned int *ind;
  495.     struct attach_lu *a_lu;
  496.     struct plu *p_lu;
  497.     struct plu_mode *p_mode;
  498.     struct pnlu *pr_lu;
  499.     struct mode *p_md;
  500.     struct pnlu *pr_t; /* Temp pointer */
  501.     struct rqb *p_rqb;
  502.     char *p;
  503.     char *pt;
  504.  
  505. #if OS_TYPE == 1
  506. /*********  Trace facility **********/
  507. unsigned int rtype;   /* type of record */
  508. unsigned int pnum;    /* point number */
  509. char pname[8];        /* name of module */
  510. char *drec;       /* record for dump */
  511. int  lenr;            /* record length */
  512.  
  513. rtype = INPROC;
  514. strcpy(pname, "lu_init");
  515. pnum = 1;
  516. drec = s_ptr;
  517. lenr = 200;
  518. gtf(rtype, pname, pnum, drec, lenr);
  519. /***********************************/
  520. #endif
  521.  
  522.     a_lu = (struct attach_lu *)s_ptr;
  523.  
  524. #if OS_TYPE == 0 /* MS_DOS */
  525.     if ((p_rqb = (struct rqb *)calloc(1, sizeof(struct rqb))) == NULL) {
  526.          a_lu -> rc = 0xf0030000; /* PORT abended */
  527.      return 0;
  528.     }
  529.     p_rqb -> th.ra.stcb = APPL_CODE;
  530.     p_rqb -> th.ra.code = p_rqb -> th.ra.code & 0xbf; /* TOP */
  531.     p_rqb -> th.ra.code |= 0x80; /* RQB */
  532.     memcpy(p_rqb->th.ra.wa.area, a_lu -> lu_name, 8);
  533.     p_rqb -> th.ra.rparm.parm.parm1 = 6; /* Attach */
  534.     p = (char *)call_appl(p_rqb);
  535.     free( p_rqb );
  536.     if (p == NULL) {
  537.          a_lu -> rc = INVALID_LU_NAME;
  538.      return 0;
  539.     }
  540. #endif
  541.  
  542.     a_lu = (struct attach_lu *)s_ptr;
  543.  
  544.     /* Set stack for entry from APPL */
  545.  
  546.     if ((altstack = malloc(2048)) == NULL) {
  547.          a_lu -> rc = 0xf0030000; /* PORT abended */
  548.      return 0;
  549.     }
  550.     altsave = altstack; /* save alt. stack address */
  551.     _asm
  552.      {
  553.         mov  ax, seg altstack
  554.         mov  es, ax
  555.         mov  bx, offset altstack
  556.         mov  ax, word ptr es:[bx]
  557.             add  ax, 2048                   ; new stack pointer
  558.         mov  word ptr es:[bx], ax
  559.          }
  560.  
  561.     p = (char *)&lu6;
  562.     memset(p, 0, sizeof(struct lucb));
  563.     psp_ini.lucb_list_ptr = &lu6;
  564.     psp_ini.tcb_list_ptr = NULL;
  565.     psp_ini.rcb_list_ptr = NULL;
  566.  
  567.     memset(&lu6, 0, sizeof(struct lucb));
  568.  
  569.     a_lu -> rc = 0; /* OK in return code */
  570.     tp_exit = a_lu -> tp_exit; /* address for TP exit routine */
  571.  
  572.     /* Initialisation LUCB block */
  573.  
  574.     pt = &((*a_lu).lu_name);
  575.     memcpy(lu6.lu_name, pt, 8);
  576. /* Set LU identification */
  577.     j = 8 - sizeof(int);
  578.     memcpy(lu6.lu_id, name_lu6, j);
  579.     addr = getpid();
  580.     ind = &(lu6.lu_id[8 - j]);
  581.     *ind = addr; /* LU_ID is set */
  582.     /* And then return it */
  583.     p = &((*a_lu).lu_id);
  584.     memcpy(p, lu6.lu_id, 8);
  585.  
  586.     lu6.lu_session_limit = a_lu -> lu_s_limit;
  587.     lu6.max_tps = a_lu -> max_tps;
  588.     lu6.cur_tps = 0;
  589.     lu6.queue_depth = a_lu -> queue_depth;
  590.  
  591.     /* Allocation and initialisation PARTNER_LU block */
  592.  
  593.     k = a_lu -> lt_plu; /* Total length of partner lu records*/
  594.     p_lu = (char *)a_lu + sizeof(struct attach_lu);
  595.                          /* Sizeof struct "attach_lu" */
  596.     pr_t = NULL;
  597.     while (k > 0) {
  598.         t = sizeof(struct plu);
  599.         p_mode = (char *)p_lu + t;
  600.         /* Allocate memory for partner_lu */
  601.         if ((pr_lu = malloc(sizeof(struct pnlu))) == NULL) {
  602.             a_lu -> rc = 0xf0030000; /* PORT abended */
  603.         return 0;
  604.         }
  605.         /* Allocate memory for mode block */
  606.         if ((p_md = malloc(sizeof(struct mode))) == NULL) {
  607.             a_lu -> rc = 0xf0030000; /* PORT abended */
  608.         return 0;
  609.         }
  610.         if (lu6.pluptr == NULL) {
  611.             lu6.pluptr = pr_lu;
  612.         }
  613.         pr_lu -> m_ptr = p_md;
  614.         pr_lu -> sess_limit = a_lu -> lu_s_limit;
  615.     p = (char *)&((*p_lu).plu_name);
  616.     pt = (char *)&((*p_mode).mode_name);
  617.  
  618.         memcpy(pr_lu -> lu_name, p, 8);
  619.         memcpy(p_md -> name, pt, 8);
  620.         p_md -> session_limit = p_mode -> mmax_neg_slim;
  621.         p_md -> ru_h_size = p_mode -> ru_h_size;
  622.         p_md -> ru_l_size = p_mode -> ru_l_size;
  623.         if (pr_t != NULL) {
  624.            pr_t -> next = pr_lu;    /* Insert in chain */
  625.         }
  626.         pr_lu -> next = NULL;
  627.         pr_lu -> lu_type = p_lu -> plu_a_num; /* LU type */
  628.         p_md -> next = NULL;
  629.         pr_t = pr_lu;
  630.         j = p_lu -> rec_lt;
  631.         k -= j;
  632.     p_lu = (char *)p_lu + p_lu -> rec_lt; /* point to next rec. if it exist */
  633.     }
  634.  
  635.     lu6.p_acb = &acb_ini;
  636.     open_acb(&acb_ini);
  637.     return (0);
  638. }
  639. int clt_vb(code, s_ptr)
  640. unsigned int code;
  641. char *s_ptr;
  642. {
  643.     struct tp_started *ts;
  644.     struct tp_ended *te;
  645.     struct tcb *t;
  646.     struct tcb *temp;
  647.     unsigned long *tpm;
  648.  
  649. #if OS_TYPE == 1
  650. /*********  Trace facility **********/
  651. unsigned int rtype;   /* type of record */
  652. unsigned int pnum;    /* point number */
  653. char pname[8];        /* name of module */
  654. char *drec;       /* record for dump */
  655. int  lenr;            /* record length */
  656.  
  657. rtype = INPROC;
  658. strcpy(pname, "clt_vb");
  659. pnum = 1;
  660. drec = s_ptr;
  661. lenr = 200;
  662. gtf(rtype, pname, pnum, drec, lenr);
  663. /***********************************/
  664. #endif
  665.  
  666.     switch (code) {
  667.         case TP_STARTED:
  668.         {
  669.         ts = (struct tp_started *)s_ptr;
  670.             ts -> rc = OK;
  671.  
  672.             if (memcmp(ts -> lu_id, lu6.lu_id, 8) != 0) {
  673.                /* Bad lu_id */
  674.                ts -> rc = 0x00000003;
  675.            return 0;
  676.             }
  677.             if (lu6.cur_tps == lu6.max_tps) {
  678.                 ts -> rc = 0x00000243; /* too_many_tps*/
  679.         return 0;
  680.             }
  681.         if ((t = calloc(1, sizeof(struct tcb))) == NULL) {
  682.                 ts -> rc = 0xf0030000; /* PORT abended */
  683.         return 0;
  684.             }
  685.             memset(t, 0, sizeof(struct tcb));
  686.             lu6.cur_tps++;
  687.             if (lu6.tcb_list_ptr == NULL) {
  688.                lu6.tcb_list_ptr = t;
  689.                t -> prev = NULL;
  690.             }
  691.             else
  692.             {
  693.                temp = lu6.tcb_list_ptr;
  694.                while (temp -> next != NULL) {
  695.                    temp = temp -> next;
  696.                }
  697.                temp -> next = t;
  698.                t -> prev = temp;
  699.             }
  700.             t -> next = NULL;
  701.             memcpy(t -> tcb_id, tpi, 4);
  702.             tpm = &((*t).tcb_id[4]);
  703.             *tpm = t;
  704.             t -> rcb_list_ptr = NULL;
  705.             t -> p_lucb = &lu6;
  706.             t -> cur_conv = 0;
  707. #if OS_TYPE == 1
  708.             p = (char *)s_ptr + sizeof(struct tp_started);
  709.             strcpy(t -> tp_name, p);
  710.             if (crtp(t) != 0) {
  711.                 ts -> rc = 0xf0030000; /* PORT abended */
  712.                 return;
  713.             }
  714. #endif
  715.             memcpy(ts -> tp_id, t -> tcb_id, 8);
  716.             break;
  717.         }
  718.         case TP_ENDED:
  719.         {
  720.         te = (struct tp_ended *)s_ptr;
  721.             te -> rc = OK;
  722.  
  723.             temp = lu6.tcb_list_ptr;
  724.             if (temp == NULL) {
  725.                 te -> rc = 0xf0040000; /* Incomplete */
  726.         return 0;
  727.             }
  728.             while (temp != NULL) {
  729.                 if (memcmp(te -> tp_id, temp -> tcb_id, 8) != 0)
  730.                     goto next_tcb;
  731.                 break;
  732.                 next_tcb:
  733.                          temp = temp -> next;
  734.             }
  735.             if (temp == NULL) {
  736.                 te -> rc = 0x00000001; /* Bad tp_id */
  737.         return 0;
  738.             }
  739.             dcp(temp);
  740.         #if OS_TYPE == 1
  741.             kill(tpst_pid, SIGKILL);
  742.         #endif
  743.         }
  744.      }
  745. }
  746. int lu_sdown(s_ptr)
  747. char *s_ptr;
  748. {
  749.     struct scb *p_scb;
  750.     struct scb *temp_scb;
  751.     struct tcb *p_tcb;
  752.     struct mode *p_mode;
  753.     struct pnlu *p_pnlu;
  754.     struct pnlu *temp_pnlu;
  755.     struct rpl *p_rpl;
  756.     struct nib *p_nib;
  757.     struct detach *d;
  758.  
  759.  
  760. #if OS_TYPE == 1
  761. /*********  Trace facility **********/
  762. unsigned int rtype;   /* type of record */
  763. unsigned int pnum;    /* point number */
  764. char pname[8];        /* name of module */
  765. char *drec;       /* record for dump */
  766. int  lenr;            /* record length */
  767.  
  768. rtype = INPROC;
  769. strcpy(pname, "lu_sdn");
  770. pnum = 1;
  771. drec = s_ptr;
  772. lenr = 200;
  773. gtf(rtype, pname, pnum, drec, lenr);
  774. /***********************************/
  775. #endif
  776.  
  777.     d = (struct detach *)s_ptr;
  778.  
  779.     /*
  780.      * Free the TCBs and RCBs.
  781.      */
  782.     p_tcb = lu6.tcb_list_ptr;
  783.     while (p_tcb != NULL) {
  784.         dcp(p_tcb);
  785.         p_tcb = p_tcb -> next;
  786.     }
  787.     /*
  788.      * Close the sessions and free SCBs and RPLs, NIBs.
  789.      */
  790.     p_scb = lu6.scb_list;
  791.     while (p_scb != NULL) {
  792.         p_rpl = p_scb -> p_rpl;
  793.         clsdst(p_rpl);
  794.         p_nib = p_rpl -> p_nib;
  795.         if (p_nib != NULL) {
  796.            free(p_nib);
  797.         }
  798.         free(p_rpl);
  799.         temp_scb = p_scb;
  800.         p_scb = p_scb -> next;
  801.         free(temp_scb);
  802.     }
  803.  
  804.     /*
  805.      * Free MODE block.
  806.      */
  807.     if ((p_mode = lu6.p_mode) != NULL) {
  808.        free(p_mode);
  809.     }
  810.  
  811.     /*
  812.      * Free PARTNER_LU blocks
  813.      */
  814.     p_pnlu = lu6.pluptr;
  815.     while (p_pnlu != NULL) {
  816.         temp_pnlu = p_pnlu;
  817.         p_pnlu = p_pnlu -> next;
  818.         free(temp_pnlu);
  819.     }
  820.     if (close_acb(&acb_ini) == -1) {
  821.         d -> rc = 0xf0030000; /* PORT abended */
  822.     }
  823.     else
  824.         d -> rc = OK;
  825.     /*
  826.      * Free input buffer for getverb.
  827.      */
  828.     if (buff != NULL) {
  829.        free(buff);
  830.     }
  831.     if (altsave != NULL) {
  832.        free(altsave);
  833.     }
  834.     freeMCB();
  835.     _disable();
  836.     _dos_setvect( 0x68, oldint68 );
  837.     _dos_freemem( ProgPrefix );  /* free Program memory */
  838. }
  839. int sessi(codex, s_ptr)
  840. unsigned int codex;
  841. struct segprf *s_ptr;  /* pointer to segment */
  842. {
  843.     struct scb *p_scb;
  844.     struct scb *temp_scb;
  845.     struct rpl *p_rpl;
  846.     struct rqb *p_rqb;
  847.     struct pnlu *pr_lu;
  848.     struct rcb *p_rcb;
  849.     struct crtp *p_crtp;
  850.     struct lucb *p_lucb;
  851.     struct tcb *p_tcb;
  852.     struct tcb *temp_tcb;
  853.     struct mode *p_mode;
  854.     char *p;
  855.     struct id {
  856.                  char id_n[4];
  857.                  unsigned long id_id;
  858.               } id_ar;
  859.     struct arcb a_rcb;
  860.     struct rcballoc rcb_a;
  861.  
  862. #if OS_TYPE == 1
  863. /*********  Trace facility **********/
  864. unsigned int rtype;   /* type of record */
  865. unsigned int pnum;    /* point number */
  866. char pname[8];        /* name of module */
  867. char *drec;       /* record for dump */
  868. int  lenr;            /* record length */
  869.  
  870. rtype = INPROC;
  871. strcpy(pname, "sessi");
  872. pnum = 1;
  873. drec = s_ptr;
  874. lenr = 200;
  875. gtf(rtype, pname, pnum, drec, lenr);
  876. /***********************************/
  877. #endif
  878.     p_rqb = (char *)s_ptr + 12;
  879.  
  880.     /************ 19.12.92 ***************/
  881.     p = (char *)s_ptr + 31;
  882.     temp_scb = lu6.scb_list;
  883.     while (temp_scb != NULL) {
  884.         if (memcmp (temp_scb->lu_name, p, 8) == 0) {
  885.        p_rpl = temp_scb->p_rpl;
  886.        p_rpl->arg = p_rqb->th.ra.wa.hh.hscb;
  887.        return;
  888.     }
  889.         temp_scb = temp_scb->next;
  890.     }
  891.    /****************************************/
  892.  
  893.     if ((p_rpl = calloc(1, sizeof(struct rpl))) == NULL) {
  894.     return 0;
  895.     }
  896.     p_rpl -> arg = p_rqb -> th.ra.wa.hh.hscb; /* Save CID in RPL*/
  897.     p_rpl -> rsrv3 = 1; /* secondary LU */
  898.     if (lu6.cur_sess == lu6.lu_session_limit) {
  899.         clsdst(p_rpl);
  900.     return 0;
  901.     }
  902.     lu6.cur_sess++;
  903.     if ((p_scb = calloc(1, sizeof(struct scb))) == NULL) {
  904.         clsdst(p_rpl);
  905.     return 0;
  906.     }
  907.     /*
  908.      * Include SCB in SCB list.
  909.      */
  910.     temp_scb = lu6.scb_list;
  911.     if (temp_scb == NULL) {
  912.         lu6.scb_list = p_scb;
  913.         p_scb -> prev = NULL;
  914.     }
  915.     else
  916.             {
  917.                 while (temp_scb -> next != NULL) {
  918.                 temp_scb = temp_scb -> next;
  919.                 }
  920.                 temp_scb -> next = p_scb;
  921.                 p_scb -> prev = temp_scb;
  922.             }
  923.     /*
  924.      * Initialisation the SCB
  925.      */
  926.     p_scb -> p_rpl = p_rpl;
  927.     p_scb -> p_rcb = NULL;
  928.     p_scb -> next = NULL;
  929.     p_scb -> use = FREE;
  930.     /*
  931.      * Fill scb.lu_name and scb.mode fields
  932.      */
  933.     p = (char *)s_ptr + 31; /* pointer to RU */
  934.     memcpy(p_scb -> lu_name, p, 8);
  935.     /*
  936.      * Try to find this LU name in
  937.      * partner LU list.
  938.      */
  939.     pr_lu = lu6.pluptr;
  940.     while (pr_lu != NULL) {
  941.         if (memcmp(pr_lu -> lu_name, p, 8) == 0) {
  942.            break;
  943.         }
  944.         pr_lu = pr_lu -> next;
  945.     }
  946.     if (pr_lu == NULL) {
  947.      /*  LU name not found */
  948.        clsdst(p_rpl);
  949.        return 0;
  950.     }
  951.     /*
  952.      * Check if it's LU type 0 ?
  953.      */
  954.     if (pr_lu -> lu_type == 0) {
  955.  
  956.       /*  Yes it's LU type 0 ! */
  957.  
  958.        p_rpl -> rsrv3 = 0; /* primary LU */
  959.        if ((p_tcb = malloc(sizeof(struct tcb))) == NULL) {
  960.            clsdst(p_rpl);
  961.        return 0;
  962.        }
  963.  
  964.       /* Include TCB in tcb chain */
  965.  
  966.        if (p_lucb -> tcb_list_ptr == NULL) {
  967.           p_lucb -> tcb_list_ptr = p_tcb;
  968.        }
  969.        else
  970.        {
  971.           temp_tcb = p_lucb -> tcb_list_ptr;
  972.           while (temp_tcb -> next != NULL) {
  973.               temp_tcb = temp_tcb -> next;
  974.           }
  975.           temp_tcb -> next = p_tcb;
  976.        }
  977.        p_tcb -> next = NULL;
  978.        p_tcb -> prev = temp_tcb;
  979.        p_tcb -> p_lucb = p_lucb;
  980.        p_tcb -> cur_conv = 1;
  981.  
  982.        /* Set tcb_id */
  983.  
  984.        memcpy(id_ar.id_n, "TPxx", 4);
  985.        id_ar.id_id = p_tcb;
  986.        memcpy(p_tcb -> tcb_id, &id_ar, 8);
  987.     /* Fill ALLOCATE_RCB record */
  988.  
  989.        memcpy(a_rcb.lu_name, p, 8);
  990.        a_rcb.p_tcb = p_tcb;
  991.        p_mode = pr_lu -> m_ptr;
  992.        memcpy(a_rcb.mode_name, p_mode -> name, 8);
  993.     /*
  994.      * ALLOCATE_RCB record is complete.
  995.      */
  996.        codex = ALLOCATE_RCB;
  997.        psrm(codex, &a_rcb, &rcb_a);
  998.        if (rcb_a.rc != OK) {
  999.            clsdst(p_rpl);
  1000.        return 0;
  1001.        }
  1002.        p_rcb = rcb_a.rcb_ptr;
  1003.        p_rcb -> sess_corl = p_rqb -> th.ra.wa.hh.hscb; /* Save CID */
  1004.        p_rcb -> conv_state = SEND;  /* Initial state for primary LU */
  1005.        p_rpl -> arg = p_rqb -> th.ra.wa.hh.hscb; /* Save CID in RPL*/
  1006.        p_rcb -> p_scb = p_scb;
  1007.        p_scb -> p_rcb = p_rcb;
  1008.        p_scb -> use = IN_USE;
  1009.        p_tcb -> rcb_list_ptr = p_rcb;
  1010.     /*
  1011.      * Fill CREATE_TP structure.
  1012.      */
  1013.        if ((p_crtp = calloc(1, sizeof(struct crtp))) == NULL) {
  1014.            clsdst(p_rpl);
  1015.        return 0;
  1016.        }
  1017.     /*
  1018.      * Initialisation the CREATE_TP record
  1019.      */
  1020.        p_crtp -> code = 0x0000;   /* data_got exit */
  1021.        p_crtp -> sense = 0;
  1022.        memcpy(p_crtp -> tp_id, p_tcb -> tcb_id, 8);
  1023.        memcpy(p_crtp -> lu_id, p_lucb -> lu_id, 8);
  1024.        p_crtp -> conv_id = p_rcb -> rcb_id;
  1025.      /*
  1026.       * Call exit subroutine for LU type 0.
  1027.       */
  1028.        calltpn(p_crtp, p_tcb);
  1029.     }
  1030. }
  1031. /*
  1032.  * Close down a session, free SCB
  1033.  */
  1034. int sessd(codex, s_ptr)
  1035. unsigned int codex;
  1036. struct rqb *s_ptr;
  1037. {
  1038.     struct scb *p_scb;
  1039.     struct scb *temp1_scb;
  1040.     struct scb *temp2_scb;
  1041.     struct tcb *p_tcb;
  1042.     struct rcb *p_rcb;
  1043.     struct rcb *temp1_rcb;
  1044.     struct rcb *temp2_rcb;
  1045.     struct rpl *p_rpl;
  1046.     struct nib *p_nib;
  1047.  
  1048.  
  1049. #if OS_TYPE == 1
  1050. /*********  Trace facility **********/
  1051. unsigned int rtype;   /* type of record */
  1052. unsigned int pnum;    /* point number */
  1053. char pname[8];        /* name of module */
  1054. char *drec;           /* record for dump */
  1055. int  lenr;            /* record length */
  1056.  
  1057. rtype = INPROC;
  1058. strcpy(pname, "sessd");
  1059. pnum = 1;
  1060. drec = s_ptr;
  1061. lenr = 200;
  1062. gtf(rtype, pname, pnum, drec, lenr);
  1063. /***********************************/
  1064. #endif
  1065.  
  1066.     /*
  1067.      * Seek SCB
  1068.      */
  1069.     p_scb = lu6.scb_list;
  1070.     while (p_scb != NULL) {
  1071.         if (memcmp(s_ptr -> th.ra.wa.area, p_scb -> lu_name, 8) != 0) {
  1072.             goto N_scb;
  1073.         }
  1074.         break;
  1075.         N_scb:
  1076.                p_scb = p_scb -> next;
  1077.     }
  1078.     if (p_scb == NULL) {
  1079.     return 0; /* SCB not found */
  1080.     }
  1081.  
  1082.     p_rpl = p_scb -> p_rpl;
  1083.     p_nib = p_rpl -> p_nib;
  1084.     if (codex == CLSSESS) {
  1085.         clsdst(p_rpl);
  1086.     }
  1087.     free(p_rpl);
  1088.     free(p_nib);
  1089.  
  1090.     if (p_scb -> p_rcb == NULL) {
  1091.         goto DelScb;
  1092.     }
  1093.     p_rcb = p_scb -> p_rcb;
  1094.     p_tcb = p_rcb -> p_tcb;
  1095.     /*
  1096.      * Delete RCB from chain
  1097.      */
  1098.     if (p_rcb -> prev == NULL) {
  1099.         p_tcb -> rcb_list_ptr = NULL;
  1100.         goto del_and_exit;
  1101.     }
  1102.     temp1_rcb = p_rcb -> prev;
  1103.     temp2_rcb = p_rcb -> next;
  1104.     temp1_rcb -> next = temp2_rcb;
  1105.     if (temp2_rcb != NULL) {
  1106.     temp2_rcb -> prev = temp1_rcb;
  1107.     }
  1108.  
  1109. del_and_exit:
  1110.  
  1111.     free(p_rcb);
  1112.     p_tcb -> cur_conv--;
  1113.  
  1114.     /*
  1115.      * Delete SCB from chain
  1116.      */
  1117.  
  1118. DelScb:
  1119.  
  1120.     if (p_scb -> prev == NULL) {
  1121.         lu6.scb_list = NULL;
  1122.         goto SessdExit;
  1123.     }
  1124.     temp1_scb = p_scb -> prev;
  1125.     temp2_scb = p_scb -> next;
  1126.     temp1_scb -> next = temp2_scb;
  1127.     if (temp2_scb != NULL) {
  1128.         temp2_scb -> prev = temp1_scb;
  1129.     }
  1130.  
  1131. SessdExit:
  1132.  
  1133.     free(p_scb);
  1134.     lu6.cur_sess--;
  1135.     return 0;
  1136. }
  1137. /*
  1138.  * Find and post RCB for received data.
  1139.  */
  1140. fpost(s_ptr)
  1141. /*
  1142.  * In case of "receive_data" sptr points to seg. prefix.
  1143.  */
  1144. struct segprf *s_ptr;
  1145. {
  1146.     struct scb *p_scb;
  1147.     struct rcb *p_rcb;
  1148.     struct rqb *p_rqb;
  1149.     char *p;
  1150.  
  1151. #if OS_TYPE == 1
  1152. /*********  Trace facility **********/
  1153. unsigned int rtype;   /* type of record */
  1154. unsigned int pnum;    /* point number */
  1155. char pname[8];        /* name of module */
  1156. char *drec;       /* record for dump */
  1157. int  lenr;            /* record length */
  1158.  
  1159. rtype = INPROC;
  1160. strcpy(pname, "fpost");
  1161. pnum = 1;
  1162. drec = s_ptr;
  1163. lenr = 200;
  1164. gtf(rtype, pname, pnum, drec, lenr);
  1165. /***********************************/
  1166. #endif
  1167.     p = (char *)s_ptr;
  1168.     p_rqb = (struct rqb *)p;
  1169.     s_ptr = (char *)p - 12;
  1170.     p = p_rqb -> th.ra.wa.area; /* OLU name */
  1171.     p_scb = lu6.scb_list;
  1172.     if (p_scb == NULL) {
  1173.         return (-1);
  1174.     }
  1175.     while (p_scb != NULL) {
  1176.       /* next is lines for CID seek.
  1177.         p_rpl = p_scb -> p_rpl;
  1178.         if (p_rpl == NULL)
  1179.             goto Next_Scb;
  1180.         if (p_rpl -> arg == *cid)
  1181.             break;        */
  1182.         if (memcmp(p, p_scb -> lu_name, 8) == 0)
  1183.             break;
  1184.  
  1185.   /* Next_Scb: */
  1186.         p_scb = p_scb -> next;
  1187.     }
  1188.     if (p_scb == NULL) {
  1189.         return (-1);
  1190.     }
  1191.     p_rcb = p_scb -> p_rcb;
  1192.     if (p_rcb == NULL) {
  1193.         return (-1);
  1194.     }
  1195.     /* RCB found !!! */
  1196.     p_rcb -> hsps = YES;
  1197.     /* This indicator must be reset by RECWAIT func. */
  1198.     rcvru(p_rcb, s_ptr);
  1199.     wait_rcb = p_rcb;
  1200. #if OS_TYPE == 0
  1201.     post_rcb(p_rcb); /* post rcb if it found in wait qeue */
  1202. #endif
  1203.     return (0);
  1204. }
  1205.